package com.gitee.deament.tianyancha.core.gencode;

import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.NumberUtil;
import cn.hutool.extra.template.engine.velocity.VelocityUtil;
import cn.hutool.http.HttpUtil;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.gitee.deament.tianyancha.core.GenColumn;
import com.sun.org.apache.bcel.internal.generic.RETURN;
import org.apache.velocity.VelocityContext;

import javax.xml.crypto.dsig.keyinfo.KeyName;
import java.io.File;
import java.lang.reflect.Type;
import java.util.*;

/**
 * @author deament
 */
public class GenEntity {
    /**
     * 基本的包路径（）
     */
    private static String modelName;
    /**
     * 子类的包路径
     */
    private static List<String> subColmonPackagePath=new ArrayList<>();

    public static void gen(String url) {
        String result = HttpUtil.get(url);
        JSONObject jsonObject = JSONObject.parseObject(result);
        JSONArray apiListJsonArray = jsonObject.getJSONObject("data").getJSONArray("items");
        if (apiListJsonArray.size() == 0) {
            System.out.println("没有接口");
            return;
        }
        Map<String, Object> contextMap = new HashMap<>(10);

        final ResourceBundle rb = ResourceBundle.getBundle("TianyanchaGen");
        for (String key : rb.keySet()) {
            String value = rb.getString(key);
            contextMap.put(key, value);

        }
        String[] excludeUrls = rb.getString("excludeUrl").split(",");


        for (int i = 0; i < apiListJsonArray.size(); i++) {
            JSONObject apiInfo = apiListJsonArray.getJSONObject(i);
            if (!apiInfo.getString("furl").equals("/services/open/hi/ic/2.0")) {
                //  continue;
            }
            boolean excludeThisUrl=false;
            for (String excludeUrl : excludeUrls) {
                if(apiInfo.getString("furl").equals(excludeUrl)){
                    //有问题的api文档跳过
                    excludeThisUrl=true;
                    break;
                }
            }
            if(excludeThisUrl){
                continue;
            }
            System.out.println(apiInfo.getString("furl"));
            contextMap.put("tianyancha", apiInfo);
            String className = getClassName(apiInfo.getString("furl"));
            contextMap.put("className", className);
            modelName=className.toLowerCase();
            contextMap.put("parent",rb.getString("parent")+"."+modelName+".entity");
            JSONObject returnParam = null;
            try {
                returnParam = JSONObject.parseObject(apiInfo.getString("returnParam").replaceAll("↵", "")).getJSONObject("result").getJSONObject("_");
            } catch (Exception e) {
                e.printStackTrace();
                System.out.println("■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■");
                System.out.println(apiInfo.getString("furl") + "该接口含有多个返回的格式");
                System.out.println("■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■");
            }
            if (returnParam == null) {
                continue;
            }
            List<GenColumn> columns = new ArrayList<>();
            //System.out.println(JSONObject.toJSONString(returnParam, true));
            for (String key : returnParam.keySet()) {
           String  javakeyName=key.replaceAll("\\(", "")
                    .replaceAll("\\.","")
                    .replaceAll("\\)", "")
                    .replaceAll("=", "");
                GenColumn column = new GenColumn();
                column.setType(returnParam.getJSONObject(key).getString("type"));
                String undefined="";
                if(column.getType()==null){
                    System.out.println("无法识别的主entity 字段:"+key+"\r\n");
                    column.setType("String");
                    undefined="(官方未定义字段类型 暂定为String)";
                }
                if(column.getRemark()!=null && column.getRemark().contains("无用")){

                    continue;
                }
                column.setName(javakeyName);
                column.setAttrName(GenUtil.captureName(javakeyName));
                column.setRemark(returnParam.getJSONObject(key).getString("remark")+undefined);
                try {
                    converNumber(column, returnParam.getJSONObject(key), className, apiInfo);
                }catch (Exception e){

                    //throw  e;
                }
                columns.add(column);
            }
            contextMap.put("columns", columns);
            //添加引用的包
            contextMap.put("subColmonPackagePaths",subColmonPackagePath) ;
            VelocityContext context = new VelocityContext(contextMap);
            File file = new File("src/main/resources/genCode/Entity.ftl");
            String gencontext = FileUtil.readUtf8String(file);
            String data = VelocityUtil.merge(gencontext, context);
            String parent = rb.getString("parent").replaceAll("\\.", "/");
            FileUtil.writeUtf8String(data, rb.getString("OutputDir") + "/" + parent +  "/"+modelName+"/" +"entity"+"/"+ className + ".java");
           //清空等待下一个
            subColmonPackagePath.clear();
        }


    }

    //属性
    public static void converNumber(GenColumn column, JSONObject jsonObject, String className,JSONObject apiInfo ) {
        JSONObject apiInfoClone = (JSONObject) apiInfo.clone();
        apiInfoClone.put("fdesc","属于"+className);
        if (column.getType().equalsIgnoreCase("number")) {
            if (column.getRemark().contains("日期") || column.getRemark().contains("时间")) {
                column.setType("Long");
            } else {
                column.setType("Integer");
            }

        }
        if (column.getType().equalsIgnoreCase("mediumtext")) {
            column.setType("String");
            column.setRemark("mediumtext "+column.getRemark());
        }


        if (column.getType().equalsIgnoreCase("array")) {
            String type ="";
            try{
                 type = jsonObject.getJSONObject("_").getJSONObject("_child").getString("type");

            }catch (Exception e){
                System.out.println(className+"遇到无法识别的字段："+JSONObject.toJSONString(jsonObject, true));
                column.setType("List<Object>");
                column.setRemark(column.getRemark()+"（无法识别的字段 请手动修改）");
                return ;
                //throw  e;
            }
            if (type.equalsIgnoreCase("number")) {
                column.setType("List<Long>");
            }else
            if (type.equalsIgnoreCase("String")) {
                column.setType("List<String>");
            } else if(type.equalsIgnoreCase("Object")){
                String subClassName = className + GenUtil.captureName(column.getName());
                JSONObject returnParam = jsonObject.getJSONObject("_").getJSONObject("_child").getJSONObject("_");
                GenSubColumn(returnParam, className, column,apiInfoClone);
                column.setType("List<" + subClassName + ">");
            }
            else {
                String subClassName = className + GenUtil.captureName(column.getName());
                column.setType("List<List<" + subClassName + ">>");
                JSONObject returnParam = jsonObject.getJSONObject("_").getJSONObject("_child").getJSONObject("_").getJSONObject("_child").getJSONObject("_");
                GenSubColumn(returnParam, className, column,apiInfoClone);
            }
        }

        if (column.getType().equalsIgnoreCase("Object")) {
            JSONObject returnParam = jsonObject.getJSONObject("_");
            GenSubColumn(returnParam, className, column,apiInfoClone);
            String subClassName = className + GenUtil.captureName(column.getName());
            column.setType("" + subClassName + "");
        }
    }

    private static void GenSubColumn(JSONObject returnParam, String className, GenColumn column ,JSONObject apiInfo) {
        Map<String, Object> contextMap = new HashMap<>(10);
        final ResourceBundle rb = ResourceBundle.getBundle("TianyanchaGen");
        for (String key : rb.keySet()) {
            String value = rb.getString(key);
            contextMap.put(key, value);
        }
        if(column.getRemark()!=null && column.getRemark().contains("无用")){

            return ;
        }
        List<GenColumn> subcolumns = new ArrayList<>();
        for (String key : returnParam.keySet()) {
            GenColumn subcolumn = new GenColumn();
            subcolumn.setType(returnParam.getJSONObject(key).getString("type"));
            if(subcolumn.getType()==null){
                subcolumn.setType("String");
            }
            subcolumn.setName(key);
            subcolumn.setAttrName(GenUtil.captureName(key));
            subcolumn.setRemark(returnParam.getJSONObject(key).getString("remark"));

            converNumber(subcolumn, returnParam.getJSONObject(key), className,apiInfo);
            subcolumns.add(subcolumn);
        }
        contextMap.put("columns", subcolumns);
        String subClassName = className + GenUtil.captureName(column.getName());
        contextMap.put("className", subClassName);
        modelName=className.toLowerCase();
        contextMap.put("parent",rb.getString("parent")+"."+modelName+".entity");
        subColmonPackagePath.add(rb.getString("parent")+"."+modelName+".entity."+subClassName);
        contextMap.put("tianyancha", apiInfo);
        VelocityContext context = new VelocityContext(contextMap);
        GenObjectColumn(rb, subClassName, context);

    }

    private static void GenObjectColumn(ResourceBundle rb, String className, VelocityContext context) {
        //生成字段名称
        File file = new File("src/main/resources/genCode/Entity.ftl");
        String gencontext = FileUtil.readUtf8String(file);
        String data = VelocityUtil.merge(gencontext, context);
        String parent = rb.getString("parent").replaceAll("\\.", "/");
        FileUtil.writeUtf8String(data, rb.getString("OutputDir") + "/" + parent  +"/"+modelName+"/entity"+"/"+ className + ".java");
    }

    //获取名称
    private static String getClassName(String fulr) {
        String module_name = fulr.split("/")[3];
        String name = fulr.split("/")[4];
        if (module_name.equalsIgnoreCase("open")) {
            module_name = "";
        }

        return (GenUtil.captureName(module_name) + GenUtil.captureName(name)).replaceAll("\\.", "");
    }

}
